package game;

import help.HelpCanvas;
import highscore.Highscore;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.media.control.VideoControl;
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Item;
import javax.microedition.m2g.SVGImage;
import javax.microedition.m2g.SVGAnimator;

import org.w3c.dom.svg.SVGElement;

import ImageLoader.ImageLoader;

import credits.CreditsCanvas;

/**
 * The Class GameMIDlet.
 */
public class GameMIDlet extends MIDlet {
	
	private Display display;
	
	private SVGImage svgImage = null;
	private SVGAnimator svgAnimator;
	
	private SVGImage svgImageNewHighScore = null;
	private SVGAnimator svgAnimatorNewHighScore;
	
	private Canvas svgCanvas;
	private Canvas svgCanvasNewHighScore;
	private MyGameCanvas gCanvas;
	
	private Thread thread = null;
	
	private HelpCanvas helpCanvas;
	private CreditsCanvas creditsCanvas;
	
	private Form introForm;
	private Player introPlayer;
	
	private Form splashForm;
	
	private Highscore highscore;

	
	/**
	 * Instantiates a new game midlet and generates all
	 * screens and loads the Intro-Video.
	 */
	public GameMIDlet() {
		display = Display.getDisplay(this);
		
		splashForm = new Form("SplashScreen");
		splashForm.setTitle(null);
		Image splashImage = ImageLoader.load("/splashScreen.jpg");
		splashForm.append(splashImage);
		
		display.setCurrent(splashForm);
		
		gCanvas = new MyGameCanvas(this);
		gCanvas.addCommand(new Command("Exit", Command.EXIT, 99));
		gCanvas.setCommandListener(new CommandListener() {
			
			public void commandAction(Command c, Displayable d) {
				if(c.getCommandType() == Command.EXIT) {
					GameMIDlet.this.gCanvas.pauseGame();
					GameMIDlet.this.showMenu();
				}
			}
		});
		helpCanvas = new HelpCanvas();
		helpCanvas.addCommand(new Command("Exit", Command.EXIT, 99));
		helpCanvas.setCommandListener(new CommandListener() {
			
			public void commandAction(Command c, Displayable d) {
				if(c.getCommandType() == Command.EXIT)
					GameMIDlet.this.showMenu();
			}
		});
		creditsCanvas = new CreditsCanvas();
		creditsCanvas.addCommand(new Command("Exit", Command.EXIT, 99));
		creditsCanvas.setCommandListener(new CommandListener() {
			
			public void commandAction(Command c, Displayable d) {
				if(c.getCommandType() == Command.EXIT)
					GameMIDlet.this.showMenu();
			}
		});
		
		introForm = new Form("video");
		loadIntroVideo();
		introForm.setTitle(null);
		introForm.addCommand(new Command("Skip", Command.EXIT, 99));
		introForm.setCommandListener(new CommandListener() {
			public void commandAction(Command c, Displayable d) {
				if(c.getCommandType() == Command.EXIT) {
					try {
						introPlayer.stop();
					} catch (MediaException e) {
						e.printStackTrace();
					}
					GameMIDlet.this.showMenu();
				}
			}
		});
		
		highscore = new Highscore();
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#startApp()
	 */
	public void startApp() {
		loadSVGMenu();
		loadSVGNewHighscore();
		
		showIntro();
		//showNewHighscoreScreen(37);
	}
	
	/**
	 * Shows the gamescreens.
	 */
	public void showGame() {
		try {
			this.svgAnimatorNewHighScore.pause();
		}
		catch(Exception e){}
		try {
			this.svgAnimator.pause();
			
			if (thread == null) {
				new Thread(this.gCanvas).start();
				this.gCanvas.continueGame();
	        }
			else {
				this.gCanvas.continueGame();
			}
			
			display.setCurrent(this.gCanvas);
		}
		catch(Exception e) {}
	}
	
	/**
	 * Shows the menuscreen.
	 */
	public void showMenu() {
		this.svgAnimator.play();
		this.gCanvas.pauseGame();
		display.setCurrent(this.svgCanvas);
	}
	
	/**
	 * Shows the highscorescreen.
	 */
	/*public void showHighscore() {
		try {
			this.svgAnimatorNewHighScore.pause();
		}
		catch(Exception e) {}
		this.svgAnimator.pause();
		this.gCanvas.pauseGame();
		//display.setCurrent(this.svgCanvas);
	}*/
	
	/**
	 * Shows the helpscreen.
	 */
	public void showHelp() {
		this.svgAnimator.pause();
		this.gCanvas.pauseGame();
		display.setCurrent(helpCanvas);
	}
	
	/**
	 * Shows the creditsscreen.
	 */
	public void showCredits() {
		this.svgAnimator.pause();
		this.gCanvas.pauseGame();
		display.setCurrent(creditsCanvas);
	}
	
	/**
	 * Shows the introscreen.
	 */
	public void showIntro() {
		//this.svgAnimator.pause();
		this.gCanvas.pauseGame();
		display.setCurrent(introForm);
		try {
			introPlayer.start();
		} catch (MediaException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Shows the new highscore screen.
	 */
	public void showNewHighscoreScreen(int points) {
		this.gCanvas.pauseGame();
		try {
			this.svgAnimator.pause();
		}
		catch(Exception e) {}
		try {
			this.svgAnimatorNewHighScore.play();
		}
		catch(Exception e) {}
		
		SVGElement elemPoints = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("points");
		elemPoints.setTrait("#text", new Integer(points).toString());
		
		if (highscore.IsNewHighscore(points)) {
			setNewHighscoreText();
			highscore.WriteNewHighscore(points);
		} else {
			setAktHighscoreText();
		}
		
		display.setCurrent(svgCanvasNewHighScore);
	}
	
	/**
	 * Load the introvideo.
	 */
	private void loadIntroVideo() {
		InputStream is = getClass().getResourceAsStream("/videos/intro.mpg");
		try {
			introPlayer = Manager.createPlayer(is, "video/mpeg");
			introPlayer.realize();
			VideoControl vc = (VideoControl)introPlayer.getControl("VideoControl");
			introForm.append((Item)vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, null));
			introPlayer.prefetch();
		} catch (IOException e) {
			System.out.println("Introvideo konnte nicht geladen werden.");
			e.printStackTrace();
		} catch (MediaException e) {
			System.out.println("Introvideo konnte nicht geladen werden.");
			e.printStackTrace();
		}
		introPlayer.addPlayerListener(new PlayerListener() {
			public void playerUpdate(Player player, String event, Object eventData) {
				if(event.compareTo(PlayerListener.END_OF_MEDIA) == 0) {
					introPlayer.close();
					showMenu();
				}
			}
		});
	}
	
	/**
	 * Loads the SVG menu.
	 */
	private void loadSVGMenu() {
		InputStream is = getClass().getResourceAsStream("/svg/Menu.svg");
		
		try {
			
			this.svgImage = (SVGImage)SVGImage.createImage(is, new ImageHandler());
			this.svgAnimator = SVGAnimator.createAnimator(this.svgImage);
			this.svgCanvas = (Canvas)this.svgAnimator.getTargetComponent();
			
			svgAnimator.setSVGEventListener(new MySVGEventListener(svgImage, this, highscore));
			
		} catch (IOException e) {
			e.printStackTrace();
		}

		svgCanvas.addCommand(new Command("Credits", Command.HELP, 1));
		svgCanvas.addCommand(new Command("Exit", Command.EXIT, 99));
		svgCanvas.setCommandListener(new CommandListener() {
			
			public void commandAction(Command c, Displayable d) {
				if(c.getCommandType() == Command.EXIT)
					GameMIDlet.this.destroyApp(true);
				if(c.getCommandType() == Command.HELP)
					GameMIDlet.this.showCredits();
			}
		});
	}
	
	/**
	 * Loads the SVG New Highscore screen.
	 */
	private void loadSVGNewHighscore() {
		InputStream is = getClass().getResourceAsStream("/svg/NewHighscore.svg");
		
		try {
			
			this.svgImageNewHighScore = (SVGImage)SVGImage.createImage(is, new ImageHandler());
			this.svgAnimatorNewHighScore = SVGAnimator.createAnimator(this.svgImageNewHighScore);
			this.svgCanvasNewHighScore = (Canvas)this.svgAnimatorNewHighScore.getTargetComponent();
			
			svgAnimatorNewHighScore.setSVGEventListener(new MySVGEventListener(svgImageNewHighScore, this, highscore));
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		svgCanvasNewHighScore.addCommand(new Command("Next", Command.EXIT, 99));
		svgCanvasNewHighScore.setCommandListener(new CommandListener() {
			public void commandAction(Command c, Displayable d) {
				if(c.getCommandType() == Command.EXIT)
					//showNewHighscoreScreen(highscore.ReadHighscore());
					GameMIDlet.this.svgAnimatorNewHighScore.pause();
					showMenu();
			}
		});
	}
	
	private void setAktHighscoreText() {
		SVGElement elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t0");
		elem.setTrait("#text", "actual highscore");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t1");
		elem.setTrait("#text", "the");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t2");
		elem.setTrait("#text", "actual");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t3");
		elem.setTrait("#text", "Highscore");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t4");
		elem.setTrait("#text", "is at");
	}
	
	private void setNewHighscoreText() {
		SVGElement elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t0");
		elem.setTrait("#text", "!!Congratulations!!");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t1");
		elem.setTrait("#text", "you");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t2");
		elem.setTrait("#text", "reached");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t3");
		elem.setTrait("#text", "a new");
		elem = (SVGElement)this.svgImageNewHighScore.getDocument().getElementById("t4");
		elem.setTrait("#text", "Highscore:");
	}
	
	public void gameOver(int points) {
		this.showNewHighscoreScreen(points);
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#pauseApp()
	 */
	public void pauseApp() {
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
	 */
	public void destroyApp(boolean unconditional) {
		//TODO
	}
}